#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>

const int N = 1e5, M = 1e5;

struct Node
{
    int l, r;
    bool flag;
};

int n, m, l;
int d[N + 5], v[N + 5], a[N + 5], p[M + 5];

long double vt(int x, int t) { return sqrtl(0.0L + 1LL * v[x] * v[x] + 2LL * a[x] * std::max(p[t] - d[x], 0)); }

int search_far(int x)
{
    int lft = 1, rgt = m, res = -1;
    while (lft <= rgt)
    {
        int mid = (lft + rgt) / 2;
        if (d[x] > p[mid])
            lft = mid + 1;
        else if (vt(x, mid) > v[0])
        {
            res = mid;
            lft = mid + 1;
        }
        else
            rgt = mid - 1;
    }
    return res;
}

int search_near(int x)
{
    int lft = 1, rgt = m, res = -1;
    while (lft <= rgt)
    {
        int mid = (lft + rgt) / 2;
        if (d[x] > p[mid])
            lft = mid + 1;
        else
        {
            res = mid;
            rgt = mid - 1;
        }
    }
    return res;
}

int main()
{
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    int t;
    std::cin >> t;
    while (t--)
    {
        std::vector<Node> arr;
        int minr = M + 5, maxr = 0;
        int ans1 = 0, ans2 = 0;

        std::cin >> n >> m >> l >> v[0];
        for (int i = 1; i <= n; i++)
            std::cin >> d[i] >> v[i] >> a[i];
        for (int i = 1; i <= m; i++)
            std::cin >> p[i];

        for (int i = 1; i <= n; i++)
            if (a[i] > 0)
                ans1 += (d[i] <= p[m] && vt(i, m) > v[0]);
            else if (a[i] == 0)
                ans1 += d[i] <= p[m] && v[i] > v[0];
            else
            {
                int far = search_far(i);
                if (far != -1)
                {
                    ans1++;
                    int near = search_near(i);
                    arr.push_back({near, far, 1});
                }
            }

        std::sort(arr.begin(), arr.end(), [](Node x, Node y)
                  {
                      if (x.l == y.l)
                          return x.r < y.r;
                      return x.l < y.l;
                  });
        for (int i = arr.size() - 1; i >= 0; i--)
        {
            if (arr[i].r >= minr)
                arr[i].flag = false;
            else
                minr = arr[i].r;
        }
        std::sort(arr.begin(), arr.end(), [](Node x, Node y)
                  {
                      if (x.flag != y.flag)
                          return x.flag > y.flag;
                      if (x.l == y.l)
                          return x.r < y.r;
                      return x.l < y.l;
                  });
        maxr = 0;
        for (auto x : arr)
            if (!x.flag)
                break;
            else
            {
                if (x.l > maxr)
                {
                    ans2++;
                    maxr = x.r;
                }
            }
        for (int i = 1; i <= n; i++)
            if ((a[i] == 0 && d[i] <= p[m] && d[i] > p[maxr]) || a[i] > 0 && search_far(i) != -1 && (d[i] < p[maxr] || (vt(i, m) > v[0]) != (vt(i, maxr) > v[0])))
            {
                ans2++;
                break;
            }
        ans2 = m - ans2;

        std::cout << ans1 << " " << ans2 << "\n";
    }

    return 0;
}
